home *** CD-ROM | disk | FTP | other *** search
/ Java Programmer's Toolkit / Java Programmer's Toolkit.iso / solaris2 / jdk / src / java / awt / componen.jav < prev    next >
Encoding:
Text File  |  1995-10-30  |  26.9 KB  |  1,106 lines

  1. /*
  2.  * @(#)Component.java    1.57 95/10/17 Arthur van Hoff
  3.  *
  4.  * Copyright (c) 1995 Sun Microsystems, Inc. All Rights Reserved.
  5.  *
  6.  * Permission to use, copy, modify, and distribute this software
  7.  * and its documentation for NON-COMMERCIAL purposes and without
  8.  * fee is hereby granted provided that this copyright notice
  9.  * appears in all copies. Please refer to the file "copyright.html"
  10.  * for further important copyright and licensing information.
  11.  *
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
  13.  * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  14.  * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  15.  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
  16.  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  17.  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  18.  */
  19. package java.awt;
  20.  
  21. import java.io.PrintStream;
  22. import java.awt.peer.ComponentPeer;
  23. import java.awt.image.ImageObserver;
  24. import java.awt.image.ImageProducer;
  25. import java.awt.image.ColorModel;
  26.  
  27. /**
  28.  * A generic Abstract Window Toolkit component. 
  29.  *
  30.  * @version     1.57, 10/17/95
  31.  * @author     Arthur van Hoff
  32.  * @author     Sami Shaio
  33.  */
  34. public abstract class Component implements ImageObserver {
  35.     /**
  36.      * The peer of the component. The peer implements the component's
  37.      * behaviour. The peer is set when the Component is added to a 
  38.      * container that also is a peer.
  39.      * @see #getPeer
  40.      * @see #addNotify
  41.      * @see #removeNotify
  42.      */
  43.     ComponentPeer peer;
  44.  
  45.     /**
  46.      * The parent of the object. It may be null for toplevel components.
  47.      * @see #getParent
  48.      */
  49.     Container parent;
  50.  
  51.     /**
  52.      * The x position of the component in the parent's coordinate system.
  53.      * @see #position
  54.      */
  55.     int x;
  56.  
  57.     /**
  58.      * The y position of the component in the parent's coordinate system.
  59.      * @see #position
  60.      */
  61.     int y;
  62.  
  63.     /**
  64.      * The width of the component.
  65.      * @see #size
  66.      */
  67.     int width;
  68.  
  69.     /**
  70.      * The height of the component.
  71.      * @see #size
  72.      */
  73.     int height;
  74.  
  75.     /**
  76.      * The foreground color for this component.
  77.      * @see #getForeground
  78.      * @see #setForeground
  79.      */
  80.     Color    foreground;
  81.  
  82.     /**
  83.      * The background color for this component.
  84.      * @see #getBackground
  85.      * @see #setBackground
  86.      */
  87.     Color    background;
  88.  
  89.     /**
  90.      * The font used by this component.
  91.      * @see #getFont
  92.      * @see #setFont
  93.      */
  94.     Font    font;
  95.  
  96.     /**
  97.      * True when the object is visible. An object that is not
  98.      * visible is not drawn on the screen.
  99.      * @see #isVisible
  100.      * @see #show
  101.      * @see #hide
  102.      */
  103.     boolean visible = true;
  104.  
  105.     /**
  106.      * True when the object is enabled. An object that is not
  107.      * enabled does not interact with the user.
  108.      * @see #isEnabled
  109.      * @see #enable
  110.      * @see #disable
  111.      */
  112.     boolean enabled = true;
  113.  
  114.     /** 
  115.      * True when the object is valid. An invalid object needs to
  116.      * be layed out. This flag is set to false when the object
  117.      * size is changed.
  118.      * @see #isValid
  119.      * @see #validate
  120.      * @see #invalidate
  121.      */
  122.     boolean valid = false;
  123.  
  124.     /**
  125.      * Constructs a new Component. Components should not be subclassed or 
  126.      * instantiated directly.
  127.      */
  128.     Component() {
  129.     }
  130.  
  131.     /**
  132.      * Gets the parent of the component.
  133.      */
  134.     public Container getParent() {
  135.     return parent;
  136.     }
  137.  
  138.     /**
  139.      * Gets the peer of the component.
  140.      */
  141.     public ComponentPeer getPeer() {
  142.     return peer;
  143.     }
  144.  
  145.     /**
  146.      * Gets the toolkit of the component. This toolkit is
  147.      * used to create the peer for this component. 
  148.      */
  149.     public Toolkit getToolkit() {
  150.     ComponentPeer peer = this.peer;
  151.     if (peer != null) {
  152.         return peer.getToolkit();
  153.     }
  154.     Container parent = this.parent;
  155.     if (parent != null) {
  156.         return parent.getToolkit();
  157.     }
  158.     return null;
  159.     }
  160.  
  161.     /**
  162.      * Checks if this Component is valid. Components are invalidated when
  163.      * the are first shown on the screen.
  164.      * @see #validate
  165.      * @see #invalidate
  166.      */
  167.     public boolean isValid() {
  168.     return (peer != null) && valid;
  169.     }
  170.  
  171.     /**
  172.      * Checks if this Component is visible. Components are initially visible 
  173.      * (with the exception of top level components such as Frame).
  174.      * @see #show
  175.      * @see #hide
  176.      */
  177.     public boolean isVisible() {
  178.     return visible;
  179.     }
  180.  
  181.     /**
  182.      * Checks if this Component is showing on screen. This means that the 
  183.      * component must be visible, and it must be in a container that is 
  184.      * visible and showing.
  185.      * @see #show
  186.      * @see #hide
  187.      */
  188.     public boolean isShowing() {
  189.     if (visible && (peer != null)) {
  190.         Container parent = this.parent;
  191.         return (parent == null) || parent.isShowing();
  192.     }
  193.     return false;
  194.     }
  195.  
  196.     /**
  197.      * Checks if this Component is enabled. Components are initially enabled.
  198.      * @see #enable
  199.      * @see #disable
  200.      */
  201.     public boolean isEnabled() {
  202.     return enabled;
  203.     }
  204.  
  205.     /** 
  206.      * Returns the current location of this component.
  207.      * The location will be in the parent's coordinate space.
  208.      * @see #move
  209.      */
  210.     public Point location() {
  211.     return new Point(x, y);
  212.     }
  213.  
  214.     /** 
  215.      * Returns the current size of this component.
  216.      * @see #resize
  217.      */
  218.     public Dimension size() {
  219.     return new Dimension(width, height);
  220.     }
  221.  
  222.     /** 
  223.      * Returns the current bounds of this component.
  224.      * @see #reshape
  225.      */
  226.     public Rectangle bounds() {
  227.     return new Rectangle(x, y, width, height);
  228.     }
  229.  
  230.     /**
  231.      * Enables a component.
  232.      * @see #isEnabled
  233.      * @see #disable
  234.      */
  235.     public synchronized void enable() {
  236.     if (!enabled) {
  237.         enabled = true;
  238.         if (peer != null) {
  239.         peer.enable();
  240.         }
  241.     }
  242.     }
  243.  
  244.     /**
  245.      * Conditionally enables a component.
  246.      * @param cond if true, enables component; disables otherwise.
  247.      * @see #enable
  248.      * @see #disable
  249.      */
  250.     public void enable(boolean cond) {
  251.     if (cond) {
  252.         enable();
  253.     } else {
  254.         disable();
  255.     }
  256.     }
  257.  
  258.     /**
  259.      * Disables a component.
  260.      * @see #isEnabled
  261.      * @see #enable
  262.      */
  263.     public synchronized void disable() {
  264.     if (enabled) {
  265.         enabled = false;
  266.         if (peer != null) {
  267.         peer.disable();
  268.         }
  269.     }
  270.     }
  271.  
  272.     /**
  273.      * Shows the component. 
  274.      * @see #isVisible
  275.      * @see #hide
  276.      */
  277.     public synchronized void show() {
  278.     if (!visible) {
  279.         visible = true;
  280.         if (peer != null) {
  281.         peer.show();
  282.         if (parent != null) {
  283.             parent.invalidate();
  284.         }
  285.         }
  286.     }
  287.     }
  288.  
  289.     /**
  290.      * Conditionally shows the component. 
  291.      * @param cond if true, it shows the component; hides otherwise.
  292.      * @see #show
  293.      * @see #hide
  294.      */
  295.     public void show(boolean cond) {
  296.     if (cond) {
  297.         show();
  298.     } else {
  299.         hide();
  300.     }
  301.     }
  302.  
  303.     /**
  304.      * Hides the component.
  305.      * @see #isVisible
  306.      * @see #hide
  307.      */
  308.     public synchronized void hide() {
  309.     if (visible) {
  310.         visible = false;
  311.         if (peer != null) {
  312.         peer.hide();
  313.         if (parent != null) {
  314.             parent.invalidate();
  315.         }
  316.         }
  317.     }
  318.     }
  319.  
  320.     /**
  321.      * Gets the foreground color. If the component does
  322.      * not have a foreground color, the foreground color
  323.      * of its parent is returned.
  324.      * @see #setForeground
  325.      */
  326.     public Color getForeground() {
  327.     Color foreground = this.foreground;
  328.     if (foreground != null) {
  329.         return foreground;
  330.     }
  331.     Container parent = this.parent;
  332.     return (parent != null) ? parent.getForeground() : null;
  333.     }
  334.  
  335.     /** 
  336.      * Sets the foreground color.
  337.      * @param c the Color
  338.      * @see #getForeground
  339.      */
  340.     public synchronized void setForeground(Color c) {
  341.     foreground = c;
  342.     if (peer != null) {
  343.         c = getForeground();
  344.         if (c != null) {
  345.         peer.setForeground(c);
  346.         }
  347.     }
  348.     }
  349.  
  350.     /**
  351.      * Gets the background color. If the component does
  352.      * not have a background color, the background color
  353.      * of its parent is returned.
  354.      * @see #setBackground
  355.      */
  356.     public Color getBackground() {
  357.     Color background = this.background;
  358.     if (background != null) {
  359.         return background;
  360.     }
  361.     Container parent = this.parent;
  362.     return (parent != null) ? parent.getBackground() : null;
  363.     }
  364.  
  365.     /** 
  366.      * Sets the background color.
  367.      * @param c the Color
  368.      * @see #getBackground
  369.      */
  370.     public synchronized void setBackground(Color c) {
  371.     background = c;
  372.     if (peer != null) {
  373.         c = getBackground();
  374.         if (c != null) {
  375.         peer.setBackground(c);
  376.         }
  377.     }
  378.     }
  379.  
  380.     /**
  381.      * Gets the font of the component. If the component does
  382.      * not have a font, the font of its parent is returned.
  383.      * @see #setFont
  384.      */
  385.     public Font getFont() {
  386.     Font font = this.font;
  387.     if (font != null) {
  388.         return font;
  389.     }
  390.     Container parent = this.parent;
  391.     return (parent != null) ? parent.getFont() : null;
  392.     }
  393.  
  394.     /** 
  395.      * Sets the font of the component.
  396.      * @param f the font
  397.      * @see #getFont
  398.      */
  399.     public synchronized void setFont(Font f) {
  400.     font = f;
  401.     if (peer != null) {
  402.         f = getFont();
  403.         if (f != null) {
  404.         peer.setFont(f);
  405.         }
  406.     }
  407.     }
  408.  
  409.     /**
  410.      * Gets the ColorModel used to display the component on the output device.
  411.      * @see ColorModel
  412.      */
  413.     public synchronized ColorModel getColorModel() {
  414.     if (peer == null) {
  415.         return null;
  416.     } else {
  417.         return peer.getColorModel();
  418.     }
  419.     }
  420.  
  421.     /** 
  422.      * Moves the Component to a new location. The x and y coordinates
  423.      * are in the parent's coordinate space.
  424.      * @param x the x coordinate
  425.      * @param y the y coordinate
  426.      * @see #location
  427.      * @see #reshape
  428.      */
  429.     public void move(int x, int y) {
  430.     reshape(x, y, width, height);
  431.     }
  432.  
  433.     /**
  434.      * Resizes the Component to the specified width and height.
  435.      * @param width the width of the component
  436.      * @param height the height of the component
  437.      * @see #size
  438.      * @see #reshape
  439.      */
  440.     public void resize(int width, int height) {
  441.     reshape(x, y, width, height);
  442.     }
  443.  
  444.     /** 
  445.      * Resizes the Component to the specified dimension.
  446.      * @param d the component dimension
  447.      * @see #size
  448.      * @see #reshape
  449.      */
  450.     public void resize(Dimension d) {
  451.     reshape(x, y, d.width, d.height);
  452.     }
  453.  
  454.     /** 
  455.      * Reshapes the Component to the specified bounding box.
  456.      * @param x the x coordinate
  457.      * @param y the y coordinate
  458.      * @param width the width of the component
  459.      * @param height the height of the component
  460.      * @see #bounds
  461.      * @see #move
  462.      * @see #resize
  463.      */
  464.     public synchronized void reshape(int x, int y, int width, int height) {
  465.     boolean resized = (this.width != width) || (this.height != height);
  466.  
  467.     if (resized || (this.x != x) || (this.y != y)) {
  468.         this.x = x;
  469.         this.y = y;
  470.         this.width = width;
  471.         this.height = height;
  472.         if (peer != null) {
  473.         peer.reshape(x, y, width, height);
  474.         if (resized) {
  475.             invalidate();
  476.         }
  477.         if (parent != null) {
  478.             parent.invalidate();
  479.         }
  480.         }
  481.     }
  482.     }
  483.  
  484.     /** 
  485.      * Returns the preferred size of this component.
  486.      * @see #minimumSize
  487.      * @see LayoutManager
  488.      */
  489.     public Dimension preferredSize() {
  490.     ComponentPeer peer = this.peer;
  491.     return (peer != null) ? peer.preferredSize() : minimumSize();
  492.     }
  493.  
  494.     /**
  495.      * Returns the minimum size of this component.
  496.      * @see #preferredSize
  497.      * @see LayoutManager
  498.      */
  499.     public Dimension minimumSize() {
  500.     ComponentPeer peer = this.peer;
  501.     return (peer != null) ? peer.minimumSize() : size();
  502.     }
  503.  
  504.     /**
  505.      * Lays out the component. This is usually called when the
  506.      * component is validated.
  507.      * @see #validate
  508.      * @see LayoutManager
  509.      */
  510.     public void layout() {
  511.     }
  512.  
  513.     /** 
  514.      * Validates a component.  
  515.      * @see #invalidate
  516.      * @see #layout
  517.      * @see LayoutManager
  518.      */
  519.     public void validate() {
  520.     while ((!valid) && (peer != null)) {
  521.         valid = true;
  522.         layout();
  523.     }
  524.     }
  525.  
  526.     /** 
  527.      * Invalidates a component.
  528.      * @see #validate
  529.      * @see #layout
  530.      * @see LayoutManager
  531.      */
  532.     public void invalidate() {
  533.     valid = false;
  534.     }
  535.  
  536.     /**
  537.      * Gets a Graphics context for this component. This method will
  538.      * return null if the component is currently not on the screen.
  539.      * @see #paint
  540.      */
  541.     public Graphics getGraphics() {
  542.     ComponentPeer peer = this.peer;
  543.     return (peer != null) ? peer.getGraphics() : null;
  544.     }
  545.  
  546.     /**
  547.      * Gets the font metrics for this component. This will
  548.      * return null if the component is currently not on the screen.
  549.      * @param font the font
  550.      * @see #getFont
  551.      */
  552.     public FontMetrics getFontMetrics(Font font) {
  553.     ComponentPeer peer = this.peer;
  554.     return (peer != null) ? peer.getFontMetrics(font) : null;
  555.     }
  556.  
  557.     /** 
  558.      * Paints the component.
  559.      * @param g the specified Graphics window
  560.      * @see #update
  561.      */
  562.     public void paint(Graphics g) {
  563.     }
  564.  
  565.     /** 
  566.      * Updates the component. This method is called in
  567.      * response to a call to repaint. You can assume that
  568.      * the background is not cleared.
  569.      * @param g the specified Graphics window
  570.      * @see #paint
  571.      * @see #repaint
  572.      */
  573.     public void update(Graphics g) {
  574.     g.setColor(getBackground());
  575.     g.fillRect(0, 0, width, height);
  576.     g.setColor(getForeground());
  577.     paint(g);
  578.     }
  579.  
  580.     /**
  581.      * Paints the component and its subcomponents.
  582.      * @param g the specified Graphics window
  583.      * @see #paint
  584.      */
  585.     public void paintAll(Graphics g) {
  586.     ComponentPeer peer = this.peer;
  587.     if (visible && (peer != null)) {
  588.         validate();
  589.         peer.paint(g);
  590.     }
  591.     }
  592.  
  593.     /** 
  594.      * Repaints the component. This will result in a
  595.      * call to update as soon as possible.
  596.      * @see #paint
  597.      */
  598.     public void repaint() {
  599.     repaint(0, 0, 0, width, height);
  600.     }
  601.  
  602.     /** 
  603.      * Repaints the component. This will result in a
  604.      * call to update within <em>tm</em> milliseconds.
  605.      * @param tm maximum time in milliseconds before update
  606.      * @see #paint
  607.      */
  608.     public void repaint(long tm) {
  609.     repaint(tm, 0, 0, width, height);
  610.     }
  611.  
  612.     /** 
  613.      * Repaints part of the component. This will result in a
  614.      * call to update as soon as possible.
  615.      * @param x the x coordinate
  616.      * @param y the y coordinate
  617.      * @param width the width 
  618.      * @param height the height 
  619.      * @see #repaint
  620.      */
  621.     public void repaint(int x, int y, int width, int height) {
  622.     repaint(0, x, y, width, height);
  623.     }
  624.  
  625.     /** 
  626.      * Repaints part of the component. This will result in a
  627.      * call to update width <em>tm</em> millseconds.
  628.      * @param tm maximum time in milliseconds before update
  629.      * @param x the x coordinate
  630.      * @param y the y coordinate
  631.      * @param width the width 
  632.      * @param height the height 
  633.      * @see #repaint
  634.      */
  635.     public void repaint(long tm, int x, int y, int width, int height) {
  636.     ComponentPeer peer = this.peer;
  637.     if ((peer != null) && (width > 0) && (height > 0)) {
  638.         peer.repaint(tm, x, y, width, height);
  639.     }
  640.     }
  641.  
  642.     /**
  643.      * Prints this component. The default implementation of this
  644.      * method calls paint.
  645.      * @param g the specified Graphics window
  646.      * @see #paint
  647.      */
  648.     public void print(Graphics g) {
  649.     paint(g);
  650.     }
  651.  
  652.     /**
  653.      * Prints the component and its subcomponents.
  654.      * @param g the specified Graphics window
  655.      * @see #print
  656.      */
  657.     public void printAll(Graphics g) {
  658.     ComponentPeer peer = this.peer;
  659.     if (visible && (peer != null)) {
  660.         validate();
  661.         peer.print(g);
  662.     }
  663.     }
  664.  
  665.     /**
  666.      * Repaints the component when the image has changed.
  667.      * @return true if image has changed; false otherwise.
  668.      */
  669.     public boolean imageUpdate(Image img, int flags,
  670.                    int x, int y, int w, int h) {
  671.     int rate = -1;
  672.     if ((flags & (FRAMEBITS|ALLBITS)) != 0) {
  673.         rate = 0;
  674.     } else if ((flags & SOMEBITS) != 0) {
  675.         String isInc = System.getProperty("awt.image.incrementaldraw");
  676.         if (isInc == null || isInc.equals("true")) {
  677.         String incRate = System.getProperty("awt.image.redrawrate");
  678.         try {
  679.             rate = (incRate != null) ? Integer.parseInt(incRate) : 100;
  680.             if (rate < 0)
  681.             rate = 0;
  682.         } catch (Exception e) {
  683.             rate = 100;
  684.         }
  685.         }
  686.     }
  687.     if (rate >= 0) {
  688.         repaint(rate, 0, 0, width, height);
  689.     }
  690.     return (flags & (ALLBITS|ERROR)) == 0;
  691.     }
  692.  
  693.     /**
  694.      * Creates an image from the specified image producer.
  695.      * @param producer the image producer
  696.      */
  697.     public Image createImage(ImageProducer producer) {
  698.     ComponentPeer peer = this.peer;
  699.     return (peer != null) ? peer.createImage(producer) : null;
  700.     }
  701.  
  702.     /**
  703.      * Creates an off-screen drawable Image to be used for double buffering.
  704.      * @param width the specified width
  705.      * @param height the specified height
  706.      */
  707.     public Image createImage(int width, int height) {
  708.     ComponentPeer peer = this.peer;
  709.     return (peer != null) ? peer.createImage(width, height) : null;
  710.     }
  711.  
  712.     /**
  713.      * Prepares an image for rendering on this Component.  The image
  714.      * data is downloaded asynchronously in another thread and the
  715.      * appropriate screen representation of the image is generated.
  716.      * @param image the Image to prepare a screen representation for
  717.      * @param observer the ImageObserver object to be notified as the
  718.      *        image is being prepared
  719.      * @return true if the image has already been fully prepared
  720.      * @see ImageObserver
  721.      */
  722.     public boolean prepareImage(Image image, ImageObserver observer) {
  723.         return prepareImage(image, -1, -1, observer);
  724.     }
  725.  
  726.     /**
  727.      * Prepares an image for rendering on this Component at the
  728.      * specified width and height.  The image data is downloaded
  729.      * asynchronously in another thread and an appropriately scaled
  730.      * screen representation of the image is generated.
  731.      * @param image the Image to prepare a screen representation for
  732.      * @param width the width of the desired screen representation
  733.      * @param height the height of the desired screen representation
  734.      * @param observer the ImageObserver object to be notified as the
  735.      *        image is being prepared
  736.      * @return true if the image has already been fully prepared
  737.      * @see ImageObserver
  738.      */
  739.     public boolean prepareImage(Image image, int width, int height,
  740.                 ImageObserver observer) {
  741.     ComponentPeer peer = this.peer;
  742.     return (peer != null)
  743.         ? peer.prepareImage(image, width, height, observer)
  744.         : false;
  745.     }
  746.  
  747.     /**
  748.      * Returns the status of the construction of a screen representation
  749.      * of the specified image.
  750.      * This method does not cause the image to begin loading, use the
  751.      * prepareImage method to force the loading of an image.
  752.      * @param image the Image to check the status of
  753.      * @param observer the ImageObserver object to be notified as the
  754.      *        image is being prepared
  755.      * @return the boolean OR of the ImageObserver flags for the
  756.      *         data that is currently available
  757.      * @see ImageObserver
  758.      * @see #prepareImage
  759.      */
  760.     public int checkImage(Image image, ImageObserver observer) {
  761.         return checkImage(image, -1, -1, observer);
  762.     }
  763.  
  764.     /**
  765.      * Returns the status of the construction of a scaled screen
  766.      * representation of the specified image.
  767.      * This method does not cause the image to begin loading, use the
  768.      * prepareImage method to force the loading of an image.
  769.      * @param image the Image to check the status of
  770.      * @param width the width of the scaled version to check the status of
  771.      * @param height the height of the scaled version to check the status of
  772.      * @param observer the ImageObserver object to be notified as the
  773.      *        image is being prepared
  774.      * @return the boolean OR of the ImageObserver flags for the
  775.      *         data that is currently available
  776.      * @see ImageObserver
  777.      * @see #prepareImage
  778.      */
  779.     public int checkImage(Image image, int width, int height,
  780.               ImageObserver observer) {
  781.     ComponentPeer peer = this.peer;
  782.     return (peer != null)
  783.         ? peer.checkImage(image, width, height, observer)
  784.         : 0;
  785.     }
  786.  
  787.     /**  
  788.      * Checks whether a specified x,y location is "inside" this
  789.      * Component. By default, x and y are inside an Component if
  790.      * they fall within the bounding box of that Component.
  791.      * @param x the x coordinate
  792.      * @param y the y coordinate
  793.      * @see #locate
  794.      */
  795.     public synchronized boolean inside(int x, int y) {
  796.     return (x >= 0) && ((x-this.x) < width) && (y >= 0) && ((y-this.y) < height);
  797.     }
  798.  
  799.     /** 
  800.      * Returns the component or subcomponent that contains the x,y location.
  801.      * @param x the x coordinate
  802.      * @param y the y coordinate
  803.      * @see #inside
  804.      */
  805.     public Component locate(int x, int y) {
  806.     return inside(x, y) ? this : null;
  807.     }
  808.  
  809.     /**
  810.      * Delivers an event to this component or one of its sub components.
  811.      * @param e the event
  812.      * @see #handleEvent
  813.      * @see #postEvent
  814.      */
  815.     public void deliverEvent(Event e) {
  816.     postEvent(e);
  817.     }
  818.  
  819.     /**
  820.      * Posts an event to this component. This will result in a call
  821.      * to handleEvent. If handleEvent returns false the event is
  822.      * passed on to the parent of this component.
  823.      * @param e the event
  824.      * @see #handleEvent
  825.      * @see #deliverEvent
  826.      */
  827.     public void postEvent(Event e) {
  828.     ComponentPeer peer = this.peer;
  829.     if ((peer != null) && peer.handleEvent(e)) {
  830.         return;
  831.     }
  832.     if (handleEvent(e)) {
  833.         return;
  834.     }
  835.     Component parent = this.parent;
  836.     if (parent != null) {
  837.         e.translate(x, y);
  838.         parent.postEvent(e);
  839.     }
  840.     }
  841.  
  842.     /**
  843.      * Handles the event. Returns true if the event is handled and
  844.      * should not be passed to the parent of this component. The default
  845.      * event handler calls some helper methods to make life easier
  846.      * on the programmer.
  847.      * @param evt the event
  848.      * @see #mouseEnter
  849.      * @see #mouseExit
  850.      * @see #mouseMove
  851.      * @see #mouseDown
  852.      * @see #mouseDrag
  853.      * @see #mouseUp
  854.      * @see #keyDown
  855.      * @see #action
  856.      */
  857.     public boolean handleEvent(Event evt) {
  858.     switch (evt.id) {
  859.       case Event.MOUSE_ENTER:
  860.         return mouseEnter(evt, evt.x, evt.y);
  861.  
  862.       case Event.MOUSE_EXIT:
  863.         return mouseExit(evt, evt.x, evt.y);
  864.  
  865.       case Event.MOUSE_MOVE:
  866.         return mouseMove(evt, evt.x, evt.y);
  867.  
  868.       case Event.MOUSE_DOWN:
  869.         return mouseDown(evt, evt.x, evt.y);
  870.  
  871.       case Event.MOUSE_DRAG:
  872.         return mouseDrag(evt, evt.x, evt.y);
  873.  
  874.       case Event.MOUSE_UP:
  875.         return mouseUp(evt, evt.x, evt.y);
  876.  
  877.       case Event.KEY_PRESS:
  878.       case Event.KEY_ACTION:
  879.         return keyDown(evt, evt.key);
  880.  
  881.       case Event.KEY_RELEASE:
  882.       case Event.KEY_ACTION_RELEASE:
  883.         return keyUp(evt, evt.key);
  884.         
  885.       case Event.ACTION_EVENT:
  886.         return action(evt, evt.arg);
  887.       case Event.GOT_FOCUS:
  888.         return gotFocus(evt, evt.arg);
  889.       case Event.LOST_FOCUS:
  890.         return lostFocus(evt, evt.arg);
  891.     }
  892.     return false;
  893.     }
  894.  
  895.     /**
  896.      * Called if the mouse is down.
  897.      * @param evt the event 
  898.      * @param x the x coordinate
  899.      * @param y the y coordinate
  900.      * @see #handleEvent
  901.      */
  902.     public boolean mouseDown(Event evt, int x, int y) {
  903.     return false;
  904.     }
  905.  
  906.     /**
  907.      * Called if the mouse is dragged (the mouse button is down).
  908.      * @param evt the event
  909.      * @param x the x coordinate
  910.      * @param y the y coordinate
  911.      * @see #handleEvent
  912.      */
  913.     public boolean mouseDrag(Event evt, int x, int y) {
  914.     return false;
  915.     }
  916.  
  917.     /**
  918.      * Called if the mouse is up.
  919.      * @param evt the event
  920.      * @param x the x coordinate
  921.      * @param y the y coordinate
  922.      * @see #handleEvent
  923.      */
  924.     public boolean mouseUp(Event evt, int x, int y) {
  925.     return false;
  926.     }
  927.  
  928.     /**
  929.      * Called if the mouse moves (the mouse button is up).
  930.      * @param evt the event
  931.      * @param x the x coordinate
  932.      * @param y the y coordinate
  933.      * @see #handleEvent
  934.      */
  935.     public boolean mouseMove(Event evt, int x, int y) {
  936.     return false;
  937.     }
  938.  
  939.     /**
  940.      * Called when the mouse enters the component.
  941.      * @param evt the event
  942.      * @param x the x coordinate
  943.      * @param y the y coordinate
  944.      * @see #handleEvent
  945.      */
  946.     public boolean mouseEnter(Event evt, int x, int y) {
  947.     return false;
  948.     }
  949.  
  950.     /**
  951.      * Called when the mouse exits the component.
  952.      * @param evt the event
  953.      * @param x the x coordinate
  954.      * @param y the y coordinate
  955.      * @see #handleEvent
  956.      */
  957.     public boolean mouseExit(Event evt, int x, int y) {
  958.     return false;
  959.     }
  960.  
  961.     /**
  962.      * Called if a character is pressed.
  963.      * @param evt the event
  964.      * @param key the key that's pressed
  965.      * @see #handleEvent
  966.      */
  967.     public boolean keyDown(Event evt, int key) {
  968.     return false;
  969.     }
  970.  
  971.     /**
  972.      * Called if a character is released.
  973.      * @param evt the event
  974.      * @param key the key that's released
  975.      * @see #handleEvent
  976.      */
  977.     public boolean keyUp(Event evt, int key) {
  978.     return false;
  979.     }
  980.  
  981.     /**
  982.      * Called if an action occurs in the Component.
  983.      * @param evt the event
  984.      * @param what the action that's occuring
  985.      * @see #handleEvent
  986.      */
  987.     public boolean action(Event evt, Object what) {
  988.     return false;
  989.     }
  990.  
  991.     /** 
  992.      * Notifies the Component to create a peer.
  993.      * @see #getPeer
  994.      * @see #removeNotify
  995.      */
  996.     public void addNotify() {
  997.     valid = false;
  998.     }
  999.  
  1000.     /** 
  1001.      * Notifies the Component to destroy the peer.
  1002.      * @see #getPeer
  1003.      * @see #addNotify
  1004.      */
  1005.     public synchronized void removeNotify() {
  1006.     if (peer != null) {
  1007.         peer.dispose();
  1008.         peer = null;
  1009.     }
  1010.     }
  1011.  
  1012.     /** 
  1013.      * Indicates that this component has received the input focus.
  1014.      * @see #requestFocus
  1015.      * @see #lostFocus
  1016.      */
  1017.     public boolean gotFocus(Event evt, Object what) {
  1018.     return false;
  1019.     }
  1020.  
  1021.     /** 
  1022.      * Indicates that this component has lost the input focus.  
  1023.      * @see #requestFocus
  1024.      * @see #gotFocus
  1025.      */
  1026.     public boolean lostFocus(Event evt, Object what) {
  1027.     return false;
  1028.     }
  1029.  
  1030.     /** 
  1031.      * Requests the input focus. The gotFocus() method will be called
  1032.      * if this method is successful.
  1033.      * @see #gotFocus
  1034.      */
  1035.     public void requestFocus() {
  1036.     ComponentPeer peer = this.peer;
  1037.     if (peer != null) {
  1038.         peer.requestFocus();
  1039.     }
  1040.     }
  1041.  
  1042.     /**
  1043.      * Moves the focus to the next component.
  1044.      * @see #requestFocus
  1045.      * @see #gotFocus
  1046.      */
  1047.      public void nextFocus() {
  1048.     ComponentPeer peer = this.peer;
  1049.      if (peer != null) {
  1050.          peer.nextFocus();
  1051.      }
  1052.      }
  1053.  
  1054.     /**
  1055.      * Returns the parameter String of this Component.
  1056.      */
  1057.     protected String paramString() {
  1058.     String str = x + "," + y + "," + width + "x" + height;
  1059.     if (!valid) {
  1060.         str += ",invalid";
  1061.     }
  1062.     if (!visible) {
  1063.         str += ",hidden";
  1064.     }
  1065.     if (!enabled) {
  1066.         str += ",disabled";
  1067.     }
  1068.     return str;
  1069.     }
  1070.  
  1071.     /**
  1072.      * Returns the String representation of this Component's values.
  1073.      */
  1074.     public String toString() {
  1075.     return getClass().getName() + "[" + paramString() + "]";
  1076.     }
  1077.  
  1078.     /**
  1079.      * Prints a listing to a print stream.
  1080.      */
  1081.     public void list() {
  1082.     list(System.out, 0);
  1083.     }
  1084.  
  1085.     /**
  1086.      * Prints a listing to the specified print out stream.
  1087.      * @param out the Stream name
  1088.      */
  1089.     public void list(PrintStream out) {
  1090.     list(out, 0);
  1091.     }
  1092.  
  1093.     /**
  1094.      * Prints out a list, starting at the specified indention, to the specified 
  1095.      * print stream.
  1096.      * @param out the Stream name
  1097.      * @param indent the start of the list 
  1098.      */
  1099.     public void list(PrintStream out, int indent) {
  1100.     for (int i = 0 ; i < indent ; i++) {
  1101.         out.print("  ");
  1102.     }
  1103.     out.println(this);
  1104.     }
  1105. }
  1106.